#pragma once

#include <algorithm>
#include <functional>
#include <vector>


namespace Zaf {
namespace Mwl {

template<typename TArg>
class Event {

	typedef std::function<void (TArg)> DelegateType;

public:
	Event() { }
	~Event() { }

	template<typename TFunc>
	Event& Register(TFunc& func) {
		m_delegates.push_back(func);
		return *this;
	}

	template<typename TObj, typename TFunc>
	Event& Register(TObj* obj, TFunc func) {
		m_delegates.push_back(std::bind(func, obj, std::placeholders::_1));
		return *this;
	}

	void Invoke(TArg arg) {
		std::for_each(m_delegates.begin(), m_delegates.end(), [ &arg ](DelegateType& dele) {
			dele(arg);
		});
	}

private:
	Event(const Event& rhs);
	const Event& operator=(const Event& rhs);

	std::vector<DelegateType> m_delegates;
};


}
}